package main

import (
	"crypto"
	"crypto/rand"
	"crypto/rsa"
	"crypto/sha256"
	"crypto/x509"
	"encoding/hex"
	"encoding/pem"
	"errors"
	"fmt"
)

var privateKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEuwIBADANBgkqhkiG9w0BAQEFAASCBKUwggShAgEAAoIBAQCRWeXwrnEcvXG+
GDtmo7xEt+07gJAKGMNEeEbdzQEpp8HI1LS/RxoPaHzNttw3zVvzhNWGEab8SoqT
g1Dj3W6/bWgyV3fu6z9BYUx2cUOStv8jCzi0LjjRaMI9LGcnZ9u7/dDyKOAmk/Jz
T+aOvMshYxBpyA1zkQHI7oXvaMOpX70lotu7PE+tEUBmC2xLr+q4rj2LddmXeBpW
0112S+9p8hD4NzNzcv9DDxcut4uKRjwSXX3EBumYwXEqC1WYWX0+3fQPJgcah7hY
b1zO9tU3pMDWFBeH+IV6/ijdv61qd3lhQT7CyKopEVt/CgU+t/U+6STsqrTfpdcr
+jgVQTe/AgMBAAECgf82gX+4wbGpFWGR54Re+QegvVg49/0LzD1tb60jf7zv4fjJ
VvpwwDkFjik++1OZmWjh6O4pWHVGJq3Qo22yBVeCcYShXCudbJpL6jDCObcdTYJf
odWhu7OS07YDOqN0I35DAOtZ4/oqfVBt7YiH/kQuQPfmsx5YOAhzUP7oyGCXIr7X
Z9PThLwquVqfepcFkAS/NMtQf/Tw+dYgDYFMhs5yQuGaB7ynUfAnEGYjLyicquuT
xyst5zKnWthXT5yKyoFOAYaTAeGuIIlxXIhl82NeAQafiR/oUCEjjIK/cs/r8jZN
+snCt+ESdAtigFhqbGQasitJTRUtxIsf4bHuxAECgYEAzUF0jEqMPLK/fGC7O2YT
tw3vioH89brCRNz4lb8UaR6w6k9OmAKcOtB0Z3txIhaqau7sGZ1v41qAXTo9Rh8m
jJtrFF2hE2jrOn3slM23BNZUQMwTpmwZJxBGCKV1nlM8ejVT/p8tLX/t2NH2vgIJ
inY6qDn7inSowJ6JfvcepY8CgYEAtUkchtJuk9EYYG3CSjqJbYIlQaYFgATjwoom
bsch6QhoRwZ6XvNahdqZNym4Sf69EHw/Zu5mBMIdFL9jhTLK0GIV/iVuZzGWlFVy
2KVLDN2aHl3WcpgJ7+DpD227O2/f+StqVipBx+LrMxueqh/27rXIbL7Dg84N1CxO
iZzoEtECgYEAxXkP9FlUiqE+cR9vgzo2BYu2xn9BK/k+Jpqh3xAzRt9sPkGGz+DT
BhK/qz+sHKvJ0Y+EPzClEQtlLEx33xrhL63nW3SpH891YJT+JDu2tUSvUpgE37xo
hpi1iGQHwQc7zCe6Y+IoyPmnj06SIUQ8gaY10NvYEeEi6g6dIjYGmikCgYAdU6iD
vwMYcpkI8Hif3Xxh9M3mIt986E2YKRUykpBPzIZiBxBA0Aly4fwrSlp/ze/z/MWc
9zAV0Pk3ZAbLg33/2/5G0PNdSk5bzL75gTP07tyB0RhiDWp+HdpWHqBNaznGa1mW
etuNZI48BFnUl7swvsOfo/SpG+psyoYiCPoaIQKBgEIXJTkq6F9NUiMScSsPp28f
tyR0Wui7XGE5d380Owll8NwkzSVz4/4mCf6JMXO0xIBEfmZAH576rogr0cj9qobD
J8KcjCZnq6SSTplu25D4NO9kTn9QvM45GBSeKL6ZqKOC+oKe2zBv7zyMxtnT9FGh
UApYuVnyEPRic9ZuidYF
-----END RSA PRIVATE KEY-----`)

var publicKey = []byte(`-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAkVnl8K5xHL1xvhg7ZqO8
RLftO4CQChjDRHhG3c0BKafByNS0v0caD2h8zbbcN81b84TVhhGm/EqKk4NQ491u
v21oMld37us/QWFMdnFDkrb/Iws4tC440WjCPSxnJ2fbu/3Q8ijgJpPyc0/mjrzL
IWMQacgNc5EByO6F72jDqV+9JaLbuzxPrRFAZgtsS6/quK49i3XZl3gaVtNddkvv
afIQ+Dczc3L/Qw8XLreLikY8El19xAbpmMFxKgtVmFl9Pt30DyYHGoe4WG9czvbV
N6TA1hQXh/iFev4o3b+tand5YUE+wsiqKRFbfwoFPrf1Pukk7Kq036XXK/o4FUE3
vwIDAQAB
-----END PUBLIC KEY-----`)

func main() {
	//rsa 密钥文件产生
	fmt.Println("获取RSA公私钥")
	prvKey, pubKey := GenRsaKey()
	fmt.Println(string(prvKey))
	fmt.Println(string(pubKey))

	fmt.Println("进行签名与验证操作")
	var data = "卧了个槽，这么神奇的吗？？！！！  ԅ(¯﹃¯ԅ) ！！！！！！）"
	fmt.Println("对消息进行签名操作...")
	signData := RsaSignWithSha256([]byte(data), privateKey)
	fmt.Println("消息的签名信息： ", hex.EncodeToString(signData))
	fmt.Println("\n对签名信息进行验证...")
	if RsaVerySignWithSha256([]byte(data), signData, publicKey) {
		fmt.Println("签名信息验证成功，确定是正确私钥签名！！")
	}

	fmt.Println("进行加密解密操作")
	ciphertext := RsaEncrypt([]byte(data), publicKey)
	fmt.Println("公钥加密后的数据：", hex.EncodeToString(ciphertext))
	sourceData := RsaDecrypt(ciphertext, privateKey)
	fmt.Println("私钥解密后的数据：", string(sourceData))
}

//RSA公钥私钥产生
func GenRsaKey() (privateKeyData, publicKeyData []byte) {
	// 生成私钥文件
	privateKey, err := rsa.GenerateKey(rand.Reader, 1024)
	if err != nil {
		panic(err)
	}
	derStream := x509.MarshalPKCS1PrivateKey(privateKey)
	block := &pem.Block{
		Type:  "RSA PRIVATE KEY",
		Bytes: derStream,
	}
	privateKeyData = pem.EncodeToMemory(block)
	publicKey := &privateKey.PublicKey
	derPkix, err := x509.MarshalPKIXPublicKey(publicKey)
	if err != nil {
		panic(err)
	}
	block = &pem.Block{
		Type:  "PUBLIC KEY",
		Bytes: derPkix,
	}
	publicKeyData = pem.EncodeToMemory(block)
	return
}

//签名
func RsaSignWithSha256(data []byte, keyBytes []byte) []byte {
	h := sha256.New()
	h.Write(data)
	hashed := h.Sum(nil)
	block, _ := pem.Decode(keyBytes)
	if block == nil {
		panic(errors.New("private key error"))
	}
	iKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		fmt.Println("ParsePKCS8PrivateKey err", err)
		panic(err)
	}

	signature, err := rsa.SignPKCS1v15(rand.Reader, iKey.(*rsa.PrivateKey), crypto.SHA256, hashed)
	if err != nil {
		fmt.Printf("Error from signing: %s\n", err)
		panic(err)
	}

	return signature
}

//验证
func RsaVerySignWithSha256(data, signData, keyBytes []byte) bool {
	block, _ := pem.Decode(keyBytes)
	if block == nil {
		panic(errors.New("public key error"))
	}
	pubKey, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		panic(err)
	}

	hashed := sha256.Sum256(data)
	err = rsa.VerifyPKCS1v15(pubKey.(*rsa.PublicKey), crypto.SHA256, hashed[:], signData)
	if err != nil {
		panic(err)
	}
	return true
}

// 公钥加密
func RsaEncrypt(data, keyBytes []byte) []byte {
	//解密pem格式的公钥
	block, _ := pem.Decode(keyBytes)
	if block == nil {
		panic(errors.New("public key error"))
	}
	// 解析公钥
	pubInterface, err := x509.ParsePKIXPublicKey(block.Bytes)
	if err != nil {
		panic(err)
	}
	// 类型断言
	pub := pubInterface.(*rsa.PublicKey)
	//加密
	ciphertext, err := rsa.EncryptPKCS1v15(rand.Reader, pub, data)
	if err != nil {
		panic(err)
	}
	return ciphertext
}

// 私钥解密
func RsaDecrypt(ciphertext, keyBytes []byte) []byte {
	//获取私钥
	block, _ := pem.Decode(keyBytes)
	if block == nil {
		panic(errors.New("private key error!"))
	}
	//解析PKCS1格式的私钥
	iKey, err := x509.ParsePKCS8PrivateKey(block.Bytes)
	if err != nil {
		panic(err)
	}
	// 解密
	data, err := rsa.DecryptPKCS1v15(rand.Reader, iKey.(*rsa.PrivateKey), ciphertext)
	if err != nil {
		panic(err)
	}
	return data
}
